home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / D.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  4.3 KB  |  130 lines

  1. #include <GL/glut.h>
  2. #include "stdlib.h"
  3. #include "math.h"
  4.  
  5. typedef enum {
  6.   RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
  7.   LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
  8. } displayLists;
  9.  
  10. /* *INDENT-OFF* */
  11. GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5},
  12.   {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16},
  13.   {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2},
  14.   {1, 2} };
  15. GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9},
  16.   {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10},
  17.   {13, 9}, {11, 11}, {9, 11} };
  18. GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0},
  19.   {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} };
  20. GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15},
  21.   {9.6, 15.25}, {9, 15.25} };
  22. GLfloat lightZeroPosition[] = {10.0, 4.0, 10.0, 1.0};
  23. GLfloat lightZeroColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */
  24. GLfloat lightOnePosition[] = {-1.0, -2.0, 1.0, 0.0};
  25. GLfloat lightOneColor[] = {0.6, 0.3, 0.2, 1.0}; /* red-tinted */
  26. GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
  27. /* *INDENT-ON* */
  28.  
  29. void
  30. extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
  31.   GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
  32. {
  33.   static GLUtriangulatorObj *tobj = NULL;
  34.   GLdouble vertex[3], dx, dy, len;
  35.   int i;
  36.   int count = dataSize / (int) (2 * sizeof(GLfloat));
  37.  
  38.   if (tobj == NULL) {
  39.     tobj = gluNewTess();  /* create and initialize a GLU
  40.                              polygon tesselation object */
  41.     gluTessCallback(tobj, GLU_BEGIN, glBegin);
  42.     gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
  43.     gluTessCallback(tobj, GLU_END, glEnd);
  44.   }
  45.   glNewList(side, GL_COMPILE);
  46.   glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing
  47.                                tessellation */
  48.   gluBeginPolygon(tobj);
  49.   for (i = 0; i < count; i++) {
  50.     vertex[0] = data[i][0];
  51.     vertex[1] = data[i][1];
  52.     vertex[2] = 0;
  53.     gluTessVertex(tobj, vertex, data[i]);
  54.   }
  55.   gluEndPolygon(tobj);
  56.   glEndList();
  57.   glNewList(edge, GL_COMPILE);
  58.   glShadeModel(GL_FLAT);  /* flat shade keeps angular hands
  59.                              from being "smoothed" */
  60.   glBegin(GL_QUAD_STRIP);
  61.   for (i = 0; i <= count; i++) {
  62.     /* mod function handles closing the edge */
  63.     glVertex3f(data[i % count][0], data[i % count][1], 0.0);
  64.     glVertex3f(data[i % count][0], data[i % count][1], thickness);
  65.     /* Calculate a unit normal by dividing by Euclidean
  66.        distance. We * could be lazy and use
  67.        glEnable(GL_NORMALIZE) so we could pass in * arbitrary
  68.        normals for a very slight performance hit. */
  69.     dx = data[(i + 1) % count][1] - data[i % count][1];
  70.     dy = data[i % count][0] - data[(i + 1) % count][0];
  71.     len = sqrt(dx * dx + dy * dy);
  72.     glNormal3f(dx / len, dy / len, 0.0);
  73.   }
  74.   glEnd();
  75.   glEndList();
  76.   glNewList(whole, GL_COMPILE);
  77.   glFrontFace(GL_CW);
  78.   glCallList(edge);
  79.   glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */
  80.   glCallList(side);
  81.   glPushMatrix();
  82.   glTranslatef(0.0, 0.0, thickness);
  83.   glFrontFace(GL_CCW);
  84.   glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */
  85.   glCallList(side);
  86.   glPopMatrix();
  87.   glEndList();
  88. }
  89.  
  90. void
  91. makeDinosaur(void)
  92. {
  93.   GLfloat bodyWidth = 3.0;
  94.  
  95.   extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
  96.     BODY_SIDE, BODY_EDGE, BODY_WHOLE);
  97.   extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
  98.     ARM_SIDE, ARM_EDGE, ARM_WHOLE);
  99.   extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
  100.     LEG_SIDE, LEG_EDGE, LEG_WHOLE);
  101.   extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
  102.     EYE_SIDE, EYE_EDGE, EYE_WHOLE);
  103.   glNewList(DINOSAUR, GL_COMPILE);
  104.   glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
  105.   glCallList(BODY_WHOLE);
  106.   glPushMatrix();
  107.   glTranslatef(0.0, 0.0, bodyWidth);
  108.   glCallList(ARM_WHOLE);
  109.   glCallList(LEG_WHOLE);
  110.   glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
  111.   glCallList(ARM_WHOLE);
  112.   glTranslatef(0.0, 0.0, -bodyWidth / 4);
  113.   glCallList(LEG_WHOLE);
  114.   glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
  115.   glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
  116.   glCallList(EYE_WHOLE);
  117.   glPopMatrix();
  118.   glEndList();
  119. }
  120.  
  121. void
  122. drawDinosaur(void) {
  123.     static int first = 1;
  124.     if (first) {
  125.     makeDinosaur();
  126.     first = 0;
  127.     }
  128.     glCallList(DINOSAUR);
  129. }
  130.